package com.csdj.article.service;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Service
public class RedisService extends MessageListenerAdapter {
    private Logger log = LoggerFactory.getLogger("redisService");

    @Resource
    private RedisTemplate<String,Object> objectRedisTemplate;

    public void setString(String key,String value,int second){
        objectRedisTemplate.opsForValue().set(key,value,second,TimeUnit.SECONDS);
    }

    public String getString(String key){
        Object o = objectRedisTemplate.opsForValue().get(key);
        if(o == null)return null;
        return o.toString();
    }

    public void setObject(String key,Object obj){
        objectRedisTemplate.opsForValue().set(key,obj);
    }

    public <T> T getObject(String key){
        Object o = objectRedisTemplate.opsForValue().get(key);
        if(o == null)return null;
        return (T)o;
    }

    public <T extends Object> T getObject(String key,Class clazz){
        Object o = objectRedisTemplate.opsForValue().get(key);
        if(o == null)return null;
        if(clazz.isInstance(o))
            if(o.getClass().getName().equalsIgnoreCase(clazz.getName())){
                return (T)o;
            }
        log.error("{}的值不是{}的实例",key,clazz.getName());
        return null;
    }
    public boolean setBit(String bulidStringKey,int offset,boolean b){
        return objectRedisTemplate.opsForValue().setBit(bulidStringKey,offset,b);
    }
    public boolean getBit(String bulidStringKey,int offset){
        return objectRedisTemplate.opsForValue().getBit(bulidStringKey,offset);
    }
    public Long bitCount(String key){
        return (Long) objectRedisTemplate.execute((RedisCallback<Long>) con-> con.bitCount(key.getBytes() ));
    }
    /**
     * redis订阅消息处理
     */
    @Override
    public void onMessage(Message message, byte[] pattern) {
//        super.onMessage(message, pattern);
        log.info("channel:{} message:{}",new String(message.getChannel()),new String(message.getBody()));
    }
    /**
     * 当key值不存在时新增缓存返回true，否则返回false
     * @param key
     * @param value
     * @return
     */
    public boolean setNx(String key, String value) {
        return objectRedisTemplate.opsForValue().setIfAbsent(key,value);
    }

    /**
     * 向redis中set集合添加值，点赞
     * @param key
     * @param value
     * @return
     */
    public void sAdd(String key,String value) {
        objectRedisTemplate.opsForSet().add(key,value);
    }

    /**
     * 向redis中set集合移除，取消点赞
     * @param key
     * @param value
     * @return
     */
    public Long srem(String key,String value) {
        return objectRedisTemplate.opsForSet().remove(key,value);
    }

    /**
     * 判断key，value是否是集中值
     * @param key
     * @param value
     * @return
     */
    public boolean isMember(String key,String value) {
        return objectRedisTemplate.opsForSet().isMember(key,value);
    }

    /**
     * 获取集合大小
     * @param key
     * @return
     */
    public Long size(String key) {
        return objectRedisTemplate.opsForSet().size(key);
    }

    /**
     * 获取集合里所有数据
     * @param key
     * @return
     */
    public Set<Object> sMembers(String key) {
        Set<Object> members = objectRedisTemplate.opsForSet().members(key);
        return members;
    }
    public Long sCard(String key) {
        return objectRedisTemplate.opsForZSet().zCard(key);
    }
}
